/* Copyright Statement:
 *
 * This software/firmware and related documentation ("AutoChips Software") are
 * protected under relevant copyright laws. The information contained herein is
 * confidential and proprietary to AutoChips Inc. and/or its licensors. Without
 * the prior written permission of AutoChips inc. and/or its licensors, any
 * reproduction, modification, use or disclosure of AutoChips Software, and
 * information contained herein, in whole or in part, shall be strictly
 * prohibited.
 *
 * AutoChips Inc. (C) 2023. All rights reserved.
 *
 * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
 * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("AUTOCHIPS SOFTWARE")
 * RECEIVED FROM AUTOCHIPS AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER
 * ON AN "AS-IS" BASIS ONLY. AUTOCHIPS EXPRESSLY DISCLAIMS ANY AND ALL
 * WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
 * NONINFRINGEMENT. NEITHER DOES AUTOCHIPS PROVIDE ANY WARRANTY WHATSOEVER WITH
 * RESPECT TO THE SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY,
 * INCORPORATED IN, OR SUPPLIED WITH THE AUTOCHIPS SOFTWARE, AND RECEIVER AGREES
 * TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO.
 * RECEIVER EXPRESSLY ACKNOWLEDGES THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO
 * OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES CONTAINED IN AUTOCHIPS
 * SOFTWARE. AUTOCHIPS SHALL ALSO NOT BE RESPONSIBLE FOR ANY AUTOCHIPS SOFTWARE
 * RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
 * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND AUTOCHIPS'S
 * ENTIRE AND CUMULATIVE LIABILITY WITH RESPECT TO THE AUTOCHIPS SOFTWARE
 * RELEASED HEREUNDER WILL BE, AT AUTOCHIPS'S OPTION, TO REVISE OR REPLACE THE
 * AUTOCHIPS SOFTWARE AT ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE
 * CHARGE PAID BY RECEIVER TO AUTOCHIPS FOR SUCH AUTOCHIPS SOFTWARE AT ISSUE.
 */

/*!
 * @file ac780x_adc_reg.h
 *
 * @brief Analog to digital converter module access register inline function definition.
 *
 */

#ifndef _AC780X_ADC_REG_H
#define _AC780X_ADC_REG_H

#ifdef __cplusplus
extern "C" {
#endif

/* ===========================================  Includes  =========================================== */
#include "ac780x_adc.h"

/* ============================================  Define  ============================================ */
#define ADC_EACH_REG_SPT0_NUM    (10UL)
#define ADC_EACH_REG_SPT1_NUM    (20UL)
#define ADC_EACH_REG_RSQ0_NUM    (6UL)
#define ADC_EACH_REG_RSQ1_NUM    (12UL)
#define ADC_EACH_REG_RSQ2_NUM    (18UL)
#define ADC_EACH_REG_IOFR_NUM    (2UL)

/* ===========================================  Typedef  ============================================ */

/* ==========================================  Variables  =========================================== */

/* ====================================  Functions declaration  ===================================== */

/* ======================================  Functions define  ======================================== */

/*!
 * @brief Set adc power mode.
 *
 * @param[in] ADCx: adc module
 *               - ADC0
 * @param[in] mode: power mode
 *               - ADC_POWER_ON
 *               - ADC_POWER_DOWN
 * @return none
 */
__STATIC_INLINE void ADC_SetPowerMode(ADC_Type *ADCx, ADC_PowerModeType mode)
{
    MODIFY_REG32(ADCx->CTRL1, ADC_CTRL1_ADON_Msk, ADC_CTRL1_ADON_Pos, mode);
}

/*!
 * @brief Get adc power mode.
 *
 * @param[in] ADCx: adc module
 *               - ADC0
 * @return power mode status
 */
__STATIC_INLINE ADC_PowerModeType ADC_GetPowerMode(ADC_Type *ADCx)
{
    return (ADC_PowerModeType)(READ_BIT32(ADCx->CTRL1, ADC_CTRL1_ADON_Msk) >> ADC_CTRL1_ADON_Pos);
}

/*!
 * @brief Set adc clock prescaler.
 *
 * @param[in] ADCx: adc module
 *               - ADC0
 * @param[in] psc: prescaler value
 *               - ADC_CLK_PRESCALER_1
 *               - ADC_CLK_PRESCALER_2
 *               - ...
 *               - ADC_CLK_PRESCALER_16
 * @return none
 */
__STATIC_INLINE void ADC_SetClockPrescaler(ADC_Type *ADCx, ADC_ClkPrescalerType psc)
{
    MODIFY_REG32(ADCx->CTRL1, ADC_CTRL1_PSC_Msk, ADC_CTRL1_PSC_Pos, psc);
}

/*!
 * @brief Get adc clock prescaler.
 *
 * @param[in] ADCx: adc module
 *               - ADC0
 * @return prescaler value
 */
__STATIC_INLINE ADC_ClkPrescalerType ADC_GetClockPrescaler(ADC_Type *ADCx)
{
    return (ADC_ClkPrescalerType)(READ_BIT32(ADCx->CTRL1, ADC_CTRL1_PSC_Msk) >> ADC_CTRL1_PSC_Pos);
}

/*!
 * @brief Set channel sample time.
 *
 * @param[in] ADCx: adc module
 *               - ADC0
 * @param[in] channel: adc channel
 *               - ADC_CH_0
 *               - ADC_CH_1
 *               - ...
 *               - ADC_CH_18
 *               - ADC_CH_VIN
 *               - ADC_CH_CALI
 * @param[in] time: sample time
 *               - ADC_SPT_CLK_8
 *               - ADC_SPT_CLK_10
 *               - ADC_SPT_CLK_15
 *               - ADC_SPT_CLK_33
 *               - ADC_SPT_CLK_64
 *               - ADC_SPT_CLK_140
 *               - ADC_SPT_CLK_215
 *               - ADC_SPT_CLK_6
 * @return none
 */
__STATIC_INLINE void ADC_SetChannelSampleTime(ADC_Type *ADCx, ADC_ChannelType channel, ADC_SampleTimeType time)
{
    if (ADC_EACH_REG_SPT0_NUM > channel)
    {
        MODIFY_REG32(ADCx->SPT0, ADC_SPT_Msk << (channel * ADC_SPT_Width), (channel * ADC_SPT_Width), time);
    }
    else if (ADC_EACH_REG_SPT1_NUM > channel)
    {
        MODIFY_REG32(ADCx->SPT1, ADC_SPT_Msk << ((channel - ADC_EACH_REG_SPT0_NUM) * ADC_SPT_Width), ((channel - ADC_EACH_REG_SPT0_NUM) * ADC_SPT_Width), time);
    }
    else
    {
        MODIFY_REG32(ADCx->SPT2, ADC_SPT_Msk << ((channel - ADC_EACH_REG_SPT1_NUM) * ADC_SPT_Width), ((channel - ADC_EACH_REG_SPT1_NUM) * ADC_SPT_Width), time);
    }
}

/*!
 * @brief Get channel sample time.
 *
 * @param[in] ADCx: adc module
 *               - ADC0
 * @param[in] channel: adc channel
 *               - ADC_CH_0
 *               - ADC_CH_1
 *               - ...
 *               - ADC_CH_18
 *               - ADC_CH_VIN
 *               - ADC_CH_CALI
 * @return sample time
 */
__STATIC_INLINE ADC_SampleTimeType ADC_GetChannelSampleTime(ADC_Type *ADCx, ADC_ChannelType channel)
{
    if (ADC_EACH_REG_SPT0_NUM > channel)
    {
        return (ADC_SampleTimeType)(READ_BIT32(ADCx->SPT0, ADC_SPT_Msk << (channel * ADC_SPT_Width)) >> (channel * ADC_SPT_Width));
    }
    else if (ADC_EACH_REG_SPT1_NUM > channel)
    {
        return (ADC_SampleTimeType)(READ_BIT32(ADCx->SPT1, ADC_SPT_Msk << ((channel - ADC_EACH_REG_SPT0_NUM) * ADC_SPT_Width)) >> ((channel - ADC_EACH_REG_SPT0_NUM) * ADC_SPT_Width));
    }
    else
    {
        return (ADC_SampleTimeType)(READ_BIT32(ADCx->SPT2, ADC_SPT_Msk << ((channel - ADC_EACH_REG_SPT1_NUM) * ADC_SPT_Width)) >> ((channel - ADC_EACH_REG_SPT1_NUM) * ADC_SPT_Width));
    }
}

/*!
 * @brief Set adc data alignment format.
 *
 * @param[in] ADCx: adc module
 *               - ADC0
 * @param[in] align: alignment format
 *               - ADC_DATA_ALIGN_RIGHT
 *               - ADC_DATA_ALIGN_LEFT
 * @return none
 */
__STATIC_INLINE void ADC_SetDataAlign(ADC_Type *ADCx, ADC_DataAlignType align)
{
    MODIFY_REG32(ADCx->CTRL0, ADC_CTRL0_ALIGN_Msk, ADC_CTRL0_ALIGN_Pos, align);
}

/*!
 * @brief Get adc data alignment format.
 *
 * @param[in] ADCx: adc module
 *               - ADC0
 * @return alignment format
 */
__STATIC_INLINE ADC_DataAlignType ADC_GetDataAlign(ADC_Type *ADCx)
{
    return (ADC_DataAlignType)(READ_BIT32(ADCx->CTRL0, ADC_CTRL0_ALIGN_Msk) >> ADC_CTRL0_ALIGN_Pos);
}

/*!
 * @brief Set scan convert mode.
 *
 * @param[in] ADCx: adc module
 *               - ADC0
 * @param[in] state: enabling state
 *               - ENABLE
 *               - DISABLE
 * @return none
 */
__STATIC_INLINE void ADC_SetScanMode(ADC_Type *ADCx, ACTION_Type state)
{
    MODIFY_REG32(ADCx->CTRL0, ADC_CTRL0_SCAN_Msk, ADC_CTRL0_SCAN_Pos, state);
}

/*!
 * @brief Get scan convert mode.
 *
 * @param[in] ADCx: adc module
 *               - ADC0
 * @return scan convert mode state
 */
__STATIC_INLINE ACTION_Type ADC_GetScanMode(ADC_Type *ADCx)
{
    return (ACTION_Type)(READ_BIT32(ADCx->CTRL0, ADC_CTRL0_SCAN_Msk) >> ADC_CTRL0_SCAN_Pos);
}

/*!
 * @brief Set continuous convert mode.
 *
 * @param[in] ADCx: adc module
 *               - ADC0
 * @param[in] state: enabling state
 *               - ENABLE
 *               - DISABLE
 * @return none
 */
__STATIC_INLINE void ADC_SetContinuousMode(ADC_Type *ADCx, ACTION_Type state)
{
    MODIFY_REG32(ADCx->CTRL0, ADC_CTRL0_CONT_Msk, ADC_CTRL0_CONT_Pos, state);
}

/*!
 * @brief Get continuous convert mode.
 *
 * @param[in] ADCx: adc module
 *               - ADC0
 * @return continuous convert mode state
 */
__STATIC_INLINE ACTION_Type ADC_GetContinuousMode(ADC_Type *ADCx)
{
    return (ACTION_Type)(READ_BIT32(ADCx->CTRL0, ADC_CTRL0_CONT_Msk) >> ADC_CTRL0_CONT_Pos);
}

/*!
 * @brief Set discontinuous mode number for regular group.
 *
 * @param[in] ADCx: adc module
 *               - ADC0
 * @param[in] num: sub group number
 *               - 0~7
 * @return none
 */
__STATIC_INLINE void ADC_SetRegularDiscontinuousNum(ADC_Type* ADCx, uint8_t num)
{
    MODIFY_REG32(ADCx->CTRL0, ADC_CTRL0_DISCNUM_Msk, ADC_CTRL0_DISCNUM_Pos, num);
}

/*!
 * @brief Get discontinuous mode number for regular group.
 *
 * @param[in] ADCx: adc module
 *               - ADC0
 * @return regular sub group number
 */
__STATIC_INLINE uint8_t ADC_GetRegularDiscontinuousNum(ADC_Type* ADCx)
{
    return (uint8_t)(READ_BIT32(ADCx->CTRL0, ADC_CTRL0_DISCNUM_Msk) >> ADC_CTRL0_DISCNUM_Pos);
}

/*!
 * @brief Set discontinuous mode for regular group.
 *
 * @param[in] ADCx: adc module
 *               - ADC0
 * @param[in] state: enabling state
 *               - ENABLE
 *               - DISABLE
 * @return none
 */
__STATIC_INLINE void ADC_SetRegularDiscontinuousMode(ADC_Type *ADCx, ACTION_Type state)
{
    MODIFY_REG32(ADCx->CTRL0, ADC_CTRL0_DISCEN_Msk, ADC_CTRL0_DISCEN_Pos, state);
}

/*!
 * @brief Get discontinuous mode for regular group.
 *
 * @param[in] ADCx: adc module
 *               - ADC0
 * @return discontinuous mode enabling state
 */
__STATIC_INLINE ACTION_Type ADC_GetRegularDiscontinuousMode(ADC_Type *ADCx)
{
    return (ACTION_Type)(READ_BIT32(ADCx->CTRL0, ADC_CTRL0_DISCEN_Msk) >> ADC_CTRL0_DISCEN_Pos);
}

/*!
 * @brief Start software trigger for regular group convert.
 *
 * @param[in] ADCx: adc module
 *               - ADC0
 * @return none
 */
__STATIC_INLINE void ADC_SoftwareStartRegularConvert(ADC_Type *ADCx)
{
    SET_BIT32(ADCx->CTRL0, ADC_CTRL0_SWSTART_Msk);
}

/*!
 * @brief Set regular group trigger source.
 *
 * @param[in] ADCx: adc module
 *               - ADC0
 * @param[in] source: trigger source
 *               - ADC_TRIGGER_EXTERNAL
 *               - ADC_TRIGGER_INTERNAL
 * @return none
 */
__STATIC_INLINE void ADC_SetRegularTriggerSource(ADC_Type *ADCx, ADC_TriggerConvertType source)
{
    MODIFY_REG32(ADCx->CTRL0, ADC_CTRL0_EXTTRIG_Msk, ADC_CTRL0_EXTTRIG_Pos, source);
}

/*!
 * @brief Get regular group trigger source.
 *
 * @param[in] ADCx: adc module
 *               - ADC0
 * @return regular group trigger source
 */
__STATIC_INLINE ADC_TriggerConvertType ADC_GetRegularTriggerSource(ADC_Type *ADCx)
{
    return (ADC_TriggerConvertType)(READ_BIT32(ADCx->CTRL0, ADC_CTRL0_EXTTRIG_Msk) >> ADC_CTRL0_EXTTRIG_Pos);
}

/*!
 * @brief Set EOC Interrupt.
 *
 * @param[in] ADCx: adc module
 *               - ADC0
 * @param[in] state: enabling state
 *               - ENABLE
 *               - DISABLE
 * @return none
 */
__STATIC_INLINE void ADC_SetEOCInterrupt(ADC_Type *ADCx, ACTION_Type state)
{
    MODIFY_REG32(ADCx->CTRL0, ADC_CTRL0_EOCIE_Msk, ADC_CTRL0_EOCIE_Pos, state);
}

/*!
 * @brief Get EOC Interrupt.
 *
 * @param[in] ADCx: adc module
 *               - ADC0
 * @return EOC Interrupt enabling state
 */
__STATIC_INLINE ACTION_Type ADC_GetEOCInterrupt(ADC_Type *ADCx)
{
    return (ACTION_Type)(READ_BIT32(ADCx->CTRL0, ADC_CTRL0_EOCIE_Msk) >> ADC_CTRL0_EOCIE_Pos);
}

/*!
 * @brief Set regular group length.
 *
 * @param[in] ADCx: adc module
 *               - ADC0
 * @param[in] length: regular group convert length
 *               - 0 ~ ADC_REGULAR_SEQUENCE_LEGNTH-1
 * @return none
 */
__STATIC_INLINE void ADC_SetRegularLength(ADC_Type *ADCx, uint8_t length)
{
    MODIFY_REG32(ADCx->RSQR3, ADC_RSQR3_RSQL_Msk, ADC_RSQR3_RSQL_Pos, length);
}

/*!
 * @brief Get regular group length.
 *
 * @param[in] ADCx: adc module
 *               - ADC0
 * @return regular group convert length
 */
__STATIC_INLINE uint8_t ADC_GetRegularLength(ADC_Type *ADCx)
{
    return (uint8_t)(READ_BIT32(ADCx->RSQR3, ADC_RSQR3_RSQL_Msk) >> ADC_RSQR3_RSQL_Pos);
}

/*!
 * @brief Set regular group sequence.
 *
 * @param[in] ADCx: adc module
 *               - ADC0
 * @param[in] channel: need to covert regular group channel
 *               - ADC_CH_0
 *               - ADC_CH_1
 *               ...
 *               - ADC_CH_CALI
 * @param[in] seq: regular group sequence
 *               - 0 ~ 20
 * @return none
 */
__STATIC_INLINE void ADC_SetRegularSequence(ADC_Type *ADCx, ADC_ChannelType channel, uint8_t seq)
{
    if (ADC_EACH_REG_RSQ0_NUM > seq)
    {
        MODIFY_REG32(ADCx->RSQR0, ADC_SQ_Msk << (seq * ADC_SQ_Width), (seq * ADC_SQ_Width), channel);
    }
    else if (ADC_EACH_REG_RSQ1_NUM > seq)
    {
        MODIFY_REG32(ADCx->RSQR1, ADC_SQ_Msk << ((seq - ADC_EACH_REG_RSQ0_NUM) * ADC_SQ_Width), ((seq - ADC_EACH_REG_RSQ0_NUM) * ADC_SQ_Width), channel);
    }
    else if (ADC_EACH_REG_RSQ2_NUM > seq)
    {
        MODIFY_REG32(ADCx->RSQR2, ADC_SQ_Msk << ((seq - ADC_EACH_REG_RSQ1_NUM) * ADC_SQ_Width), ((seq - ADC_EACH_REG_RSQ1_NUM) * ADC_SQ_Width), channel);
    }
    else
    {
        MODIFY_REG32(ADCx->RSQR3, ADC_SQ_Msk << ((seq - ADC_EACH_REG_RSQ2_NUM) * ADC_SQ_Width), ((seq - ADC_EACH_REG_RSQ2_NUM) * ADC_SQ_Width), channel);
    }
}

/*!
 * @brief Get regular group sequence.
 *
 * @param[in] ADCx: adc module
 *               - ADC0
 * @param[in] seq: regular group sequence
 *               - 0 ~ 20
 * @return need to covert regular group channel
 */
__STATIC_INLINE ADC_ChannelType ADC_GetRegularSequence(ADC_Type *ADCx, uint8_t seq)
{
    if (ADC_EACH_REG_RSQ0_NUM > seq)
    {
        return (ADC_ChannelType)(READ_BIT32(ADCx->RSQR0, ADC_SQ_Msk << (seq * ADC_SQ_Width)) >> (seq * ADC_SQ_Width));
    }
    else if (ADC_EACH_REG_RSQ1_NUM > seq)
    {
        return (ADC_ChannelType)(READ_BIT32(ADCx->RSQR1, ADC_SQ_Msk << ((seq - ADC_EACH_REG_RSQ0_NUM) * ADC_SQ_Width)) >> ((seq - ADC_EACH_REG_RSQ0_NUM) * ADC_SQ_Width));
    }
    else if (ADC_EACH_REG_RSQ2_NUM > seq)
    {
        return (ADC_ChannelType)(READ_BIT32(ADCx->RSQR2, ADC_SQ_Msk << ((seq - ADC_EACH_REG_RSQ1_NUM) * ADC_SQ_Width)) >> ((seq - ADC_EACH_REG_RSQ1_NUM) * ADC_SQ_Width));
    }
    else
    {
        return (ADC_ChannelType)(READ_BIT32(ADCx->RSQR3, ADC_SQ_Msk << ((seq - ADC_EACH_REG_RSQ2_NUM) * ADC_SQ_Width)) >> ((seq - ADC_EACH_REG_RSQ2_NUM) * ADC_SQ_Width));
    }
}

/*!
 * @brief Get regular group data.
 *
 * @param[in] ADCx: adc module
 *               - ADC0
 * @return regular group data
 */
__STATIC_INLINE uint32_t ADC_GetRegularData(ADC_Type *ADCx)
{
    return (ADCx->RDR);
}

/*!
 * @brief Enable DMA mode.
 *
 * This function just use for regular group
 *
 * @param[in] ADCx: adc module
 *               - ADC0
 * @param[in] state: enabling state
 *               - ENABLE
 *               - DISABLE
 * @return none
 */
__STATIC_INLINE void ADC_SetDMA(ADC_Type *ADCx, ACTION_Type state)
{
    MODIFY_REG32(ADCx->CTRL0, ADC_CTRL0_DMAEN_Msk, ADC_CTRL0_DMAEN_Pos, state);
}

/*!
 * @brief Get DMA state.
 *
 * This function just use for regular group
 *
 * @param[in] ADCx: adc module
 *               - ADC0
 * @return DMA enabling state
 */
__STATIC_INLINE ACTION_Type ADC_GetDMA(ADC_Type *ADCx)
{
    return (ACTION_Type)(READ_BIT32(ADCx->CTRL0, ADC_CTRL0_DMAEN_Msk) >> ADC_CTRL0_DMAEN_Pos);
}

/*!
 * @brief Start software trigger for injected group convert.
 *
 * @param[in] ADCx: adc module
 *               - ADC0
 * @return none
 */
__STATIC_INLINE void ADC_SoftwareStartInjectConvert(ADC_Type *ADCx)
{
    SET_BIT32(ADCx->CTRL0, ADC_CTRL0_ISWSTART_Msk);
}

/*!
 * @brief Set injected group trigger source.
 *
 * @param[in] ADCx: adc module
 *               - ADC0
 * @param[in] source: trigger source
 *               - ADC_TRIGGER_EXTERNAL
 *               - ADC_TRIGGER_INTERNAL
 * @return none
 */
__STATIC_INLINE void ADC_SetInjectTriggerSource(ADC_Type *ADCx, ADC_TriggerConvertType source)
{
    MODIFY_REG32(ADCx->CTRL0, ADC_CTRL0_IEXTTRIG_Msk, ADC_CTRL0_IEXTTRIG_Pos, source);
}

/*!
 * @brief Get injected group trigger source.
 *
 * @param[in] ADCx: adc module
 *               - ADC0
 * @return injected group trigger source
 */
__STATIC_INLINE ADC_TriggerConvertType ADC_GetInjectTriggerSource(ADC_Type *ADCx)
{
    return (ADC_TriggerConvertType)(READ_BIT32(ADCx->CTRL0, ADC_CTRL0_IEXTTRIG_Msk) >> ADC_CTRL0_IEXTTRIG_Pos);
}

/*!
 * @brief Set IEOC Interrupt.
 *
 * @param[in] ADCx: adc module
 *               - ADC0
 * @param[in] state: enabling state
 *               - ENABLE
 *               - DISABLE
 * @return none
 */
__STATIC_INLINE void ADC_SetIEOCInterrupt(ADC_Type *ADCx, ACTION_Type state)
{
    MODIFY_REG32(ADCx->CTRL0, ADC_CTRL0_IEOCIE_Msk, ADC_CTRL0_IEOCIE_Pos, state);
}

/*!
 * @brief Get IEOC Interrupt.
 *
 * @param[in] ADCx: adc module
 *               - ADC0
 * @return IEOC Interrupt enabling state
 */
__STATIC_INLINE ACTION_Type ADC_GetIEOCInterrupt(ADC_Type *ADCx)
{
    return (ACTION_Type)(READ_BIT32(ADCx->CTRL0, ADC_CTRL0_IEOCIE_Msk) >> ADC_CTRL0_IEOCIE_Pos);
}

/*!
 * @brief Set injected group length.
 *
 * @param[in] ADCx: adc module
 *               - ADC0
 * @param[in] length: injected group convert length
 *               - 0 ~ ADC_INJECT_SEQUENCE_LEGNTH-1
 * @return none
 */
__STATIC_INLINE void ADC_SetInjectLength(ADC_Type *ADCx, uint8_t length)
{
    MODIFY_REG32(ADCx->ISQR, ADC_ISQR_ISQL_Msk, ADC_ISQR_ISQL_Pos, length);
}

/*!
 * @brief Get injected group length.
 *
 * @param[in] ADCx: adc module
 *               - ADC0
 * @return injected group convert length
 */
__STATIC_INLINE uint8_t ADC_GetInjectLength(ADC_Type *ADCx)
{
    return (uint8_t)(READ_BIT32(ADCx->ISQR, ADC_ISQR_ISQL_Msk) >> ADC_ISQR_ISQL_Pos);
}

/*!
 * @brief Set injected group sequence.
 *
 * @param[in] ADCx: adc module
 *               - ADC0
 * @param[in] channel: need to covert regular group channel
 *               - ADC_CH_0
 *               - ADC_CH_1
 *               ...
 *               - ADC_CH_CALI
 * @param[in] seq: injected group sequence
 *               - 0 ~ 3
 * @return none
 */
__STATIC_INLINE void ADC_SetInjectSequence(ADC_Type *ADCx, ADC_ChannelType channel, uint8_t seq)
{
    MODIFY_REG32(ADCx->ISQR, ADC_SQ_Msk << (seq * ADC_SQ_Width), (seq * ADC_SQ_Width), channel);
}

/*!
 * @brief Get injected group sequence.
 *
 * @param[in] ADCx: adc module
 *               - ADC0
 * @param[in] seq: injected group sequence
 *               - 0 ~ 3
 * @return need to covert regular group channel
 */
__STATIC_INLINE ADC_ChannelType ADC_GetInjectSequence(ADC_Type *ADCx, uint8_t seq)
{
    return (ADC_ChannelType)(READ_BIT32(ADCx->ISQR, ADC_SQ_Msk << (seq * ADC_SQ_Width)) >> (seq * ADC_SQ_Width));
}

/*!
 * @brief Set injected group offset value.
 *
 * @param[in] ADCx: adc module
 *               - ADC0
 * @param[in] num: injected group channel number
 *               - 0 ~ 3
 * @param[in] offset: Offset Value
 *               - 0 ~ 0xfff
 * @return none
 */
__STATIC_INLINE void ADC_SetInjectOffset(ADC_Type *ADCx, uint8_t num, uint32_t offset)
{
    if (ADC_EACH_REG_IOFR_NUM > num)
    {
        MODIFY_REG32(ADCx->IOFR0, ADC_IOFR_Msk << (num * ADC_IOFR_Width), (num * ADC_IOFR_Width), offset);
    }
    else
    {
        MODIFY_REG32(ADCx->IOFR1, ADC_IOFR_Msk << ((num - ADC_EACH_REG_IOFR_NUM) * ADC_IOFR_Width), ((num - ADC_EACH_REG_IOFR_NUM) * ADC_IOFR_Width), offset);
    }
}

/*!
 * @brief Get injected group offset value.
 *
 * @param[in] ADCx: adc module
 *               - ADC0
 * @param[in] num: injected group channel number
 *               - 0 ~ 3
 * @return injected group Offset Value
 */
__STATIC_INLINE uint32_t ADC_GetInjectOffset(ADC_Type *ADCx, uint8_t num)
{
    if (ADC_EACH_REG_IOFR_NUM > num)
    {
        return (uint32_t)(READ_BIT32(ADCx->IOFR0, ADC_IOFR_Msk << (num * ADC_IOFR_Width)) >> (num * ADC_IOFR_Width));
    }
    else
    {
        return (uint32_t)(READ_BIT32(ADCx->IOFR1, ADC_IOFR_Msk << ((num - ADC_EACH_REG_IOFR_NUM) * ADC_IOFR_Width)) >> ((num - ADC_EACH_REG_IOFR_NUM) * ADC_IOFR_Width));
    }
}

/*!
 * @brief Get injected group data.
 *
 * @param[in] ADCx: adc module
 *               - ADC0
 * @param[in] num: injected group channel number
 *               - 0 ~ 3
 * @return injected group data
 */
__STATIC_INLINE uint32_t ADC_GetInjectData(ADC_Type *ADCx, int num)
{
    return (ADCx->IDR[num]);
}

/*!
 * @brief Set ADC automatic injected group convert after regular complete.
 *
 * @param[in] ADCx: adc module
 *               - ADC0
 * @param[in] state: enabling state
 *               - ENABLE
 *               - DISABLE
 * @return none
 */
__STATIC_INLINE void ADC_SetInjectAutoMode(ADC_Type *ADCx, ACTION_Type state)
{
    MODIFY_REG32(ADCx->CTRL0, ADC_CTRL0_IAUTO_Msk, ADC_CTRL0_IAUTO_Pos, state);
}

/*!
 * @brief Get ADC automatic injected group convert after regular complete.
 *
 * @param[in] ADCx: adc module
 *               - ADC0
 * @return automatic injected group enabling state
 */
__STATIC_INLINE ACTION_Type ADC_GetInjectAutoMode(ADC_Type *ADCx)
{
    return (ACTION_Type)(READ_BIT32(ADCx->CTRL0, ADC_CTRL0_IAUTO_Msk) >> ADC_CTRL0_IAUTO_Pos);
}

/*!
 * @brief Set ADC interval mode.
 *
 * Can only be configured in mode3/5, other modes do not work
 *
 * @param[in] ADCx: adc module
 *               - ADC0
 * @param[in] state: enabling state
 *               - ENABLE
 *               - DISABLE
 * @return none
 */
__STATIC_INLINE void ADC_SetIntervalMode(ADC_Type *ADCx, ACTION_Type state)
{
    MODIFY_REG32(ADCx->CTRL0, ADC_CTRL0_INTERVAL_Msk, ADC_CTRL0_INTERVAL_Pos, state);
}

/*!
 * @brief Get ADC interval mode.
 *
 * Can only be configured in mode3/5, other modes do not work
 *
 * @param[in] ADCx: adc module
 *               - ADC0
 * @return interval mode enabling state
 */
__STATIC_INLINE ACTION_Type ADC_GetIntervalMode(ADC_Type *ADCx)
{
    return (ACTION_Type)(READ_BIT32(ADCx->CTRL0, ADC_CTRL0_INTERVAL_Msk) >> ADC_CTRL0_INTERVAL_Pos);
}

/*!
 * @brief Set discontinuous mode for injected group.
 *
 * @param[in] ADCx: adc module
 *               - ADC0
 * @param[in] state: enabling state
 *               - ENABLE
 *               - DISABLE
 * @return none
 */
__STATIC_INLINE void ADC_SetInjectDiscontinuousMode(ADC_Type *ADCx, ACTION_Type state)
{
    MODIFY_REG32(ADCx->CTRL0, ADC_CTRL0_IDISCEN_Msk, ADC_CTRL0_IDISCEN_Pos, state);
}

/*!
 * @brief Get discontinuous mode for injected group.
 *
 * @param[in] ADCx: adc module
 *               - ADC0
 * @return discontinuous mode for injected group enabling state
 */
__STATIC_INLINE ACTION_Type ADC_GetInjectDiscontinuousMode(ADC_Type *ADCx)
{
    return (ACTION_Type)(READ_BIT32(ADCx->CTRL0, ADC_CTRL0_IDISCEN_Msk) >> ADC_CTRL0_IDISCEN_Pos);
}

/*!
 * @brief Set AMO Interrupt.
 *
 * @param[in] ADCx: adc module
 *               - ADC0
 * @param[in] state: enabling state
 *               - ENABLE
 *               - DISABLE
 * @return none
 */
__STATIC_INLINE void ADC_SetAMOInterrupt(ADC_Type *ADCx, ACTION_Type state)
{
    MODIFY_REG32(ADCx->CTRL0, ADC_CTRL0_AMOIE_Msk, ADC_CTRL0_AMOIE_Pos, state);
}

/*!
 * @brief Get AMO Interrupt.
 *
 * @param[in] ADCx: adc module
 *               - ADC0
 * @return AMO Interrupt enabling state
 */
__STATIC_INLINE ACTION_Type ADC_GetAMOInterrupt(ADC_Type *ADCx)
{
    return (ACTION_Type)(READ_BIT32(ADCx->CTRL0, ADC_CTRL0_AMOIE_Msk) >> ADC_CTRL0_AMOIE_Pos);
}

/*!
 * @brief Set analog monitor single channel.
 *
 * @param[in] ADCx: adc module
 *               - ADC0
 * @param[in] channel: analog monitor channel
 *               - ADC_CH_0
 *               - ADC_CH_1
 *               ...
 *               - ADC_CH_CALI
 * @return none
 */
__STATIC_INLINE void ADC_SetAMOSingleChannel(ADC_Type *ADCx, ADC_ChannelType channel)
{
    MODIFY_REG32(ADCx->CTRL0, ADC_CTRL0_AMOCH_Msk, ADC_CTRL0_AMOCH_Pos, channel);
}

/*!
 * @brief Get analog monitor single channel.
 *
 * @param[in] ADCx: adc module
 *               - ADC0
 * @return analog monitor channel
 */
__STATIC_INLINE ADC_ChannelType ADC_GetAMOSingleChannel(ADC_Type *ADCx)
{
    return (ADC_ChannelType)(READ_BIT32(ADCx->CTRL0, ADC_CTRL0_AMOCH_Msk) >> ADC_CTRL0_AMOCH_Pos);
}

/*!
 * @brief Set analog monitor single channel mode.
 *
 * @param[in] ADCx: adc module
 *               - ADC0
 * @param[in] state: enabling state
 *               - ENABLE
 *               - DISABLE
 * @return none
 */
__STATIC_INLINE void ADC_SetAMOSingleChannelMode(ADC_Type *ADCx, ACTION_Type state)
{
    MODIFY_REG32(ADCx->CTRL0, ADC_CTRL0_AMOSGL_Msk, ADC_CTRL0_AMOSGL_Pos, state);
}

/*!
 * @brief Get analog monitor single channel mode.
 *
 * @param[in] ADCx: adc module
 *               - ADC0
 * @return analog monitor single channel mode enabling state
 */
__STATIC_INLINE ACTION_Type ADC_GetAMOSingleChannelMode(ADC_Type *ADCx)
{
    return (ACTION_Type)(READ_BIT32(ADCx->CTRL0, ADC_CTRL0_AMOSGL_Msk) >> ADC_CTRL0_AMOSGL_Pos);
}

/*!
 * @brief Set regular group analog monitor mode.
 *
 * @param[in] ADCx: adc module
 *               - ADC0
 * @param[in] state: enabling state
 *               - ENABLE
 *               - DISABLE
 * @return none
 */
__STATIC_INLINE void ADC_SetAMORegularMode(ADC_Type *ADCx, ACTION_Type state)
{
    MODIFY_REG32(ADCx->CTRL0, ADC_CTRL0_AMOEN_Msk, ADC_CTRL0_AMOEN_Pos, state);
}

/*!
 * @brief Get regular group analog monitor mode.
 *
 * @param[in] ADCx: adc module
 *               - ADC0
 * @return regular group analog monitor mode enabling state
 */
__STATIC_INLINE ACTION_Type ADC_GetAMORegularMode(ADC_Type *ADCx)
{
    return (ACTION_Type)(READ_BIT32(ADCx->CTRL0, ADC_CTRL0_AMOEN_Msk) >> ADC_CTRL0_AMOEN_Pos);
}

/*!
 * @brief Set injected group analog monitor mode.
 *
 * @param[in] ADCx: adc module
 *               - ADC0
 * @param[in] state: enabling state
 *               - ENABLE
 *               - DISABLE
 * @return none
 */
__STATIC_INLINE void ADC_SetAMOInjectMode(ADC_Type *ADCx, ACTION_Type state)
{
    MODIFY_REG32(ADCx->CTRL0, ADC_CTRL0_IAMOEN_Msk, ADC_CTRL0_IAMOEN_Pos, state);
}

/*!
 * @brief Get injected group analog monitor mode.
 *
 * @param[in] ADCx: adc module
 *               - ADC0
 * @return injected group analog monitor mode enabling state
 */
__STATIC_INLINE ACTION_Type ADC_GetAMOInjectMode(ADC_Type *ADCx)
{
    return (ACTION_Type)(READ_BIT32(ADCx->CTRL0, ADC_CTRL0_IAMOEN_Msk) >> ADC_CTRL0_IAMOEN_Pos);
}

/*!
 * @brief Set analog monitor trigger type.
 *
 * @param[in] ADCx: adc module
 *               - ADC0
 * @param[in] mode: amo trigger mode
 *               - ADC_AMO_TRIGGER_LEVEL
 *               - ADC_AMO_TRIGGER_EDGE
 * @return none
 */
__STATIC_INLINE void ADC_SetAMOTriggerMode(ADC_Type *ADCx, ADC_AMOTriggerModeType mode)
{
    MODIFY_REG32(ADCx->CTRL0, ADC_CTRL0_AMOMODE_Msk, ADC_CTRL0_AMOMODE_Pos, mode);
}

/*!
 * @brief Get analog monitor trigger type.
 *
 * @param[in] ADCx: adc module
 *               - ADC0
 * @return analog monitor trigger type
 */
__STATIC_INLINE ADC_AMOTriggerModeType ADC_GetAMOTriggerMode(ADC_Type *ADCx)
{
    return (ADC_AMOTriggerModeType)(READ_BIT32(ADCx->CTRL0, ADC_CTRL0_AMOMODE_Msk) >> ADC_CTRL0_AMOMODE_Pos);
}

/*!
 * @brief Set analog monitor threshold.
 *
 * @param[in] ADCx: adc module
 *               - ADC0
 * @param[in] highValue: high threshold value
 *               - 0~0xfff
 * @param[in] lowValue: low threshold value
 *               - 0~0xfff
 * @return none
 */
__STATIC_INLINE void ADC_SetAMOThreshold(ADC_Type *ADCx, uint16_t highValue, uint16_t lowValue)
{
    MODIFY_REG32(ADCx->AMOHR, ADC_AMOHR_AMOHT_Msk, ADC_AMOHR_AMOHT_Pos, highValue);
    MODIFY_REG32(ADCx->AMOLR, ADC_AMOLR_AMOLT_Msk, ADC_AMOLR_AMOLT_Pos, lowValue);
}

/*!
 * @brief Get analog monitor high threshold value.
 *
 * @param[in] ADCx: adc module
 *               - ADC0
 * @return AMOHT threshold value
 */
__STATIC_INLINE uint16_t ADC_GetAMOHThreshold(ADC_Type *ADCx)
{
    return (uint16_t)(READ_BIT32(ADCx->AMOHR, ADC_AMOHR_AMOHT_Msk) >> ADC_AMOHR_AMOHT_Pos);
}

/*!
 * @brief Get analog monitor low threshold value.
 *
 * @param[in] ADCx: adc module
 *               - ADC0
 * @return AMOLT threshold value
 */
__STATIC_INLINE uint16_t ADC_GetAMOLThreshold(ADC_Type *ADCx)
{
    return (uint16_t)(READ_BIT32(ADCx->AMOLR, ADC_AMOLR_AMOLT_Msk) >> ADC_AMOLR_AMOLT_Pos);
}

/*!
 * @brief Set analog monitor offset.
 *
 * @param[in] ADCx: adc module
 *               - ADC0
 * @param[in] highOffset: high offset value
 *               - 0~0xfff
 * @param[in] lowOffset: low offset value
 *               - 0~0xfff
 * @return none
 */
__STATIC_INLINE void ADC_SetAMOOffset(ADC_Type *ADCx, uint16_t highOffset, uint16_t lowOffset)
{
    MODIFY_REG32(ADCx->AMOHR, ADC_AMOHR_AMOHO_Msk, ADC_AMOHR_AMOHO_Pos, highOffset);
    MODIFY_REG32(ADCx->AMOLR, ADC_AMOLR_AMOLO_Msk, ADC_AMOLR_AMOLO_Pos, lowOffset);
}

/*!
 * @brief Get analog monitor high offset.
 *
 * @param[in] ADCx: adc module
 *               - ADC0
 * @return AMOHO Offset value
 */
__STATIC_INLINE uint16_t ADC_GetAMOHOffset(ADC_Type *ADCx)
{
    return (uint16_t)(READ_BIT32(ADCx->AMOHR, ADC_AMOHR_AMOHO_Msk) >> ADC_AMOHR_AMOHO_Pos);
}

/*!
 * @brief Get analog monitor low offset.
 *
 * @param[in] ADCx: adc module
 *               - ADC0
 * @return AMOLO Offset value
 */
__STATIC_INLINE uint16_t ADC_GetAMOLOffset(ADC_Type *ADCx)
{
    return (uint16_t)(READ_BIT32(ADCx->AMOLR, ADC_AMOLR_AMOLO_Msk) >> ADC_AMOLR_AMOLO_Pos);
}

/*!
 * @brief Get AMO flag.
 *
 * @param[in] ADCx: adc module
 *               - ADC0
 * @return AMO flag
 */
__STATIC_INLINE uint32_t ADC_GetAMOFlag(ADC_Type *ADCx)
{
    return (READ_BIT32(ADCx->STR, ADC_STR_AMO_Msk) >> ADC_STR_AMO_Pos);
}

/*!
 * @brief Clear AMO flag.
 *
 * @param[in] ADCx: adc module
 *               - ADC0
 * @return none
 */
__STATIC_INLINE void ADC_ClearAMOFlag(ADC_Type *ADCx)
{
    ADCx->STR = ADC_STR_AMO_Msk;
}

/*!
 * @brief Get EOC flag.
 *
 * @param[in] ADCx: adc module
 *               - ADC0
 * @return EOC flag
 */
__STATIC_INLINE uint32_t ADC_GetEOCFlag(ADC_Type *ADCx)
{
    return (READ_BIT32(ADCx->STR, ADC_STR_EOC_Msk) >> ADC_STR_EOC_Pos);
}

/*!
 * @brief Clear EOC flag.
 *
 * @param[in] ADCx: adc module
 *               - ADC0
 * @return none
 */
__STATIC_INLINE void ADC_ClearEOCFlag(ADC_Type *ADCx)
{
    ADCx->STR = ADC_STR_EOC_Msk;
}

/*!
 * @brief Get IEOC flag.
 *
 * @param[in] ADCx: adc module
 *               - ADC0
 * @return IEOC flag
 */
__STATIC_INLINE uint32_t ADC_GetIEOCFlag(ADC_Type *ADCx)
{
    return (READ_BIT32(ADCx->STR, ADC_STR_IEOC_Msk) >> ADC_STR_IEOC_Pos);
}

/*!
 * @brief Clear IEOC flag.
 *
 * @param[in] ADCx: adc module
 *               - ADC0
 * @return none
 */
__STATIC_INLINE void ADC_ClearIEOCFlag(ADC_Type *ADCx)
{
    ADCx->STR = ADC_STR_IEOC_Msk;
}

/*!
 * @brief Get idle flag.
 *
 * @param[in] ADCx: adc module
 *               - ADC0
 * @return idle flag
 */
__STATIC_INLINE uint32_t ADC_GetIdleFlag(ADC_Type *ADCx)
{
    return (READ_BIT32(ADCx->STR, ADC_STR_IDLE_Msk) >> ADC_STR_IDLE_Pos);
}

/*!
 * @brief Get normal analog monitor flag.
 *
 * @param[in] ADCx: adc module
 *               - ADC0
 * @return NAMO flag
 */
__STATIC_INLINE uint32_t ADC_GetNAMOFlag(ADC_Type *ADCx)
{
    return (READ_BIT32(ADCx->STR, ADC_STR_NAMO_Msk) >> ADC_STR_NAMO_Pos);
}

/*!
 * @brief Clear normal analog monitor flag.
 *
 * @param[in] ADCx: adc module
 *               - ADC0
 * @return none
 */
__STATIC_INLINE void ADC_ClearNAMOFlag(ADC_Type *ADCx)
{
    ADCx->STR = ADC_STR_NAMO_Msk;
}

/*!
 * @brief Get abnormal analog monitor flag.
 *
 * @param[in] ADCx: adc module
 *               - ADC0
 * @return AAMO flag
 */
__STATIC_INLINE uint32_t ADC_GetAAMOFlag(ADC_Type *ADCx)
{
    return (READ_BIT32(ADCx->STR, ADC_STR_AAMO_Msk) >> ADC_STR_AAMO_Pos);
}

/*!
 * @brief Clear abnormal analog monitor flag.
 *
 * @param[in] ADCx: adc module
 *               - ADC0
 * @return none
 */
__STATIC_INLINE void ADC_ClearAAMOFlag(ADC_Type *ADCx)
{
    ADCx->STR = ADC_STR_AAMO_Msk;
}

/*!
 * @brief Get regular group data overflow flag.
 *
 * @param[in] ADCx: adc module
 *               - ADC0
 * @return RGOF flag
 */
__STATIC_INLINE uint32_t ADC_GetRGOFFlag(ADC_Type *ADCx)
{
    return (READ_BIT32(ADCx->STR, ADC_STR_RGOF_Msk) >> ADC_STR_RGOF_Pos);
}

/*!
 * @brief Clear regular group data overflow flag.
 *
 * @param[in] ADCx: adc module
 *               - ADC0
 * @return none
 */
__STATIC_INLINE void ADC_ClearRGOFFlag(ADC_Type *ADCx)
{
    ADCx->STR = ADC_STR_RGOF_Msk;
}

/*!
 * @brief Set Calibration function.
 *
 * @param[in] ADCx: adc module
 *               - ADC0
 * @param[in] state: enabling state
 *               - ENABLE
 *               - DISABLE
 * @return none
 */
__STATIC_INLINE void ADC_SetCalibration(ADC_Type *ADCx, ACTION_Type state)
{
    MODIFY_REG32(ADCx->CTRL1, ADC_CTRL1_CALEN_Msk, ADC_CTRL1_CALEN_Pos, state);
}

/*!
 * @brief Get Calibration function.
 *
 * @param[in] ADCx: adc module
 *               - ADC0
 * @return calibration enabling state
 */
__STATIC_INLINE ACTION_Type ADC_GetCalibration(ADC_Type *ADCx)
{
    return (ACTION_Type)(READ_BIT32(ADCx->CTRL1, ADC_CTRL1_CALEN_Msk) >> ADC_CTRL1_CALEN_Pos);
}

/*!
 * @brief Set Low power mode conversion interval.
 *
 * @param[in] ADCx: adc module
 *               - ADC0
 * @param[in] channel: Low power mode conversion interval
 *               - ADC_CONVERSION_INTERVAL_1MS
 *               - ADC_CONVERSION_INTERVAL_2MS
 *               ...
 *               - ADC_CONVERSION_INTERVAL_10MS
 * @return none
 */
__STATIC_INLINE void ADC_SetLPConversionInterval(ADC_Type *ADCx, ADC_ConversionIntervalType interval)
{
    MODIFY_REG32(ADCx->CTRL1, ADC_CTRL1_LPCONVINT_Msk, ADC_CTRL1_LPCONVINT_Pos, interval);
}

/*!
 * @brief Get Low power mode conversion interval.
 *
 * @param[in] ADCx: adc module
 *               - ADC0
 * @return Low power mode conversion interval
 */
__STATIC_INLINE ADC_ConversionIntervalType ADC_GetLPConversionInterval(ADC_Type *ADCx)
{
    return (ADC_ConversionIntervalType)(READ_BIT32(ADCx->CTRL1, ADC_CTRL1_LPCONVINT_Msk) >> ADC_CTRL1_LPCONVINT_Pos);
}

/*!
 * @brief Get ADC external channel gain error & offset error setting.
 *
 * @param[in] ADCx: adc module
 *              - ADC0
 * @param[out] gain: current gain error value setting in LSB
 * @param[out] offset: current offsest error value setting in LSB
 */
__STATIC_INLINE void ADC_GetExternalGainOffset(const ADC_Type *ADCx, int16_t *gain, int16_t *offset)
{
    *gain = (int16_t)((uint16_t)(READ_BIT32(ADCx->CGV, ADC_CGV_GE1_Msk) >> ADC_CGV_GE1_Pos) << 3U) >> 3U;
    *offset = (int16_t)((uint16_t)(READ_BIT32(ADCx->COV, ADC_COV_OE1_Msk) >> ADC_COV_OE1_Pos) << 4U) >> 4U;
}

/*!
 * @brief Set ADC external channel gain error & offset error.
 *
 * @param[in] ADCx: adc module
 *              - ADC0
 * @param[in] gain: gain error value setting in LSB
 * @param[in] offset: offsest error value setting in LSB
 */
__STATIC_INLINE void ADC_SetExternalGainOffset(ADC_Type *ADCx, int16_t gain, int16_t offset)
{
    uint16_t gainValue = gain, offsetValue = offset;
    MODIFY_REG32(ADCx->CGV, ADC_CGV_GE1_Msk, ADC_CGV_GE1_Pos, gainValue);
    MODIFY_REG32(ADCx->COV, ADC_COV_OE1_Msk, ADC_COV_OE1_Pos, offsetValue);
}

/*!
 * @brief Get ADC internal channel gain error & offset error setting.
 *
 * @param[in] ADCx: adc module
 *              - ADC0
 * @param[out] gain: current gain error value setting in LSB
 * @param[out] offset: current offsest error value setting in LSB
 */
__STATIC_INLINE void ADC_GetInternalGainOffset(const ADC_Type *ADCx, int16_t *gain, int16_t *offset)
{
    *gain = (int16_t)((uint16_t)(READ_BIT32(ADCx->CGV, ADC_CGV_GE0_Msk) >> ADC_CGV_GE0_Pos) << 3U) >> 3U;
    *offset = (int16_t)((uint16_t)(READ_BIT32(ADCx->COV, ADC_COV_OE0_Msk) >> ADC_COV_OE0_Pos) << 4U) >> 4U;
}

/*!
 * @brief Set ADC internal channel gain error & offset error.
 *
 * @param[in] ADCx: adc module
 *              - ADC0
 * @param[in] gain: gain error value setting in LSB
 * @param[in] offset: offsest error value setting in LSB
 */
__STATIC_INLINE void ADC_SetInternalGainOffset(ADC_Type *ADCx, int16_t gain, int16_t offset)
{
    uint16_t gainValue = gain, offsetValue = offset;
    MODIFY_REG32(ADCx->CGV, ADC_CGV_GE0_Msk, ADC_CGV_GE0_Pos, gainValue);
    MODIFY_REG32(ADCx->COV, ADC_COV_OE0_Msk, ADC_COV_OE0_Pos, offsetValue);
}

/*!
 * @brief Set ADC reference voltage source.
 *
 * @param[in] ADCx: adc module
 *               - ADC0
 * @param[in] state: ADC reference voltage source
 *               - ADC_VOLTAGEREF_VDDA
 *               - ADC_VOLTAGEREF_AGPIO
 *               - ADC_VOLTAGEREF_VREF
 * @return none
 */
__STATIC_INLINE void ADC_SetVREFSource(ADC_Type *ADCx, ADC_VrefType state)
{
    MODIFY_REG32(ADCx->CFG0, ADC_CFG0_VREF_SEL_Msk, ADC_CFG0_VREF_SEL_Pos, state);
}

/*!
 * @brief Get ADC reference voltage source.
 *
 * @param[in] ADCx: adc module
 *               - ADC0
 * @return ADC reference voltage source
 */
__STATIC_INLINE ADC_VrefType ADC_GetVREFSource(ADC_Type *ADCx)
{
    return (ADC_VrefType)(READ_BIT32(ADCx->CFG0, ADC_CFG0_VREF_SEL_Msk) >> ADC_CFG0_VREF_SEL_Pos);
}

/*!
 * @brief Set ADC GE/OE calibration signal enable or disable.
 *
 * @param[in] ADCx: adc module
 *               - ADC0
 * @param[in] state: enabling state
 *               - ENABLE
 *               - DISABLE
 * @return none
 */
__STATIC_INLINE void ADC_SetGEOECali(ADC_Type *ADCx, ACTION_Type state)
{
    MODIFY_REG32(ADCx->CFG0, ADC_CFG0_GEOECAL_EN_Msk, ADC_CFG0_GEOECAL_EN_Pos, state);
}

/*!
 * @brief Get ADC GE/OE calibration signal.
 *
 * @param[in] ADCx: adc module
 *               - ADC0
 * @return ADC GE/OE calibration signal enabling state
 */
__STATIC_INLINE ACTION_Type ADC_GetGEOECali(ADC_Type *ADCx)
{
    return (ACTION_Type)(READ_BIT32(ADCx->CFG0, ADC_CFG0_GEOECAL_EN_Msk) >> ADC_CFG0_GEOECAL_EN_Pos);
}

/*!
 * @brief Set ADC internal calibration signal voltage.
 *
 * @param[in] ADCx: adc module
 *               - ADC0
 * @param[in] state: calibration signal select
 *               - ADC_CALI_SIGNAL_FLOATING
 *               - ADC_CALI_SIGNAL_VREF1_8
 *               - ADC_CALI_SIGNAL_VREF2_8
 *               - ADC_CALI_SIGNAL_VREF3_8
 *               - ADC_CALI_SIGNAL_VREF4_8
 *               - ADC_CALI_SIGNAL_VREF5_8
 *               - ADC_CALI_SIGNAL_VREF6_8
 *               - ADC_CALI_SIGNAL_VREF7_8
 * @return none
 */
__STATIC_INLINE void ADC_SetGEOECaliSignal(ADC_Type *ADCx, ADC_GEOEType state)
{
    MODIFY_REG32(ADCx->CFG0, ADC_CFG0_GEOE_SEL_Msk, ADC_CFG0_GEOE_SEL_Pos, state);
}

/*!
 * @brief Get ADC internal calibration signal voltage.
 *
 * @param[in] ADCx: adc module
 *               - ADC0
 * @return ADC internal calibration signal voltage state
 */
__STATIC_INLINE ADC_GEOEType ADC_GetGEOECaliSignal(ADC_Type *ADCx)
{
    return (ADC_GEOEType)(READ_BIT32(ADCx->CFG0, ADC_CFG0_GEOE_SEL_Msk) >> ADC_CFG0_GEOE_SEL_Pos);
}

/*!
 * @brief Set ADC BG and T-sensor channel state.
 *
 * @param[in] ADCx: adc module
 *               - ADC0
 * @param[in] state: enabling state
 *               - ENABLE
 *               - DISABLE
 * @return none
 */
__STATIC_INLINE void ADC_SetInternalChannelState(ADC_Type *ADCx, ACTION_Type state)
{
    MODIFY_REG32(ADCx->CFG0, ADC_CFG0_VBUF_EN_Msk, ADC_CFG0_VBUF_EN_Pos, state);
}

/*!
 * @brief Get ADC BG and T-sensor channel state.
 *
 * @param[in] ADCx: adc module
 *               - ADC0
 * @return ADC BG and T-sensor channel enabling state
 */
__STATIC_INLINE ACTION_Type ADC_GetInternalChannelState(ADC_Type *ADCx)
{
    return (ACTION_Type)(READ_BIT32(ADCx->CFG0, ADC_CFG0_VBUF_EN_Msk) >> ADC_CFG0_VBUF_EN_Pos);
}

/*!
 * @brief Set ADC internal channel.
 *
 * @param[in] ADCx: adc module
 *               - ADC0
 * @param[in] state: internal signal setting
 *               - ADC_INTERNAL_BG
 *               - ADC_INTERNAL_TSENSOR
 * @return none
 */
__STATIC_INLINE void ADC_SetInternalChannel(ADC_Type *ADCx, ADC_VINType state)
{
    MODIFY_REG32(ADCx->CFG1, ADC_CFG1_MON_SEL_Msk, ADC_CFG1_MON_SEL_Pos, state);
}

/*!
 * @brief Get ADC VIN channel select.
 *
 * @param[in] ADCx: adc module
 *               - ADC0
 * @return ADC VIN channel state
*/
__STATIC_INLINE ADC_VINType ADC_GetInternalChannel(ADC_Type *ADCx)
{
    return (ADC_VINType)(READ_BIT32(ADCx->CFG1, ADC_CFG1_MON_SEL_Msk) >> ADC_CFG1_MON_SEL_Pos);
}

#ifdef __cplusplus
}
#endif

#endif /* _AC780X_ADC_REG_H */

/* =============================================  EOF  ============================================== */
